/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package src.j2ee.compumake.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import src.j2ee.compumake.dominio.DiscoDuro;
import src.j2ee.compumake.dominio.Gabinete;
import src.j2ee.compumake.dominio.Memoria;
import src.j2ee.compumake.dominio.Monitor;
import src.j2ee.compumake.dominio.Procesador;
import src.j2ee.compumake.dominio.Producto;
import src.j2ee.compumake.dominio.Raton;
import src.j2ee.compumake.dominio.Sucursal;
import src.j2ee.compumake.dominio.TarjetaMadre;
import src.j2ee.compumake.dominio.TarjetaVideo;
import src.j2ee.compumake.dominio.Teclado;
import src.j2ee.compumake.dominio.UnidadOptica;

/************************************************************************
 **                                                                    **
 ** Nombre: DAOProducto.java                                           **
 ** Version: v1.0.0                                                    **
 ** Autor: amado.cante                                                 **
 ** Creado: 20/04/2013                                                 **
 ** Modificado:                                                        **
 ** Diagrama:                                                          **
 ** Caso de uso:                                                       **
 **                                                                    **
 ***********************************************************************/
public class DAOProducto {
    private static final String TABLA_PRODUCTOS = "Productos";
    private static final String TABLA_EXISTENCIAS = "Existencias";
    private static final String COLUMNA_ID_PRODUCTO_EXISTENCIAS = "idProducto";
    private static final String COLUMNA_TIPO_PRODUCTO = "tipoProducto";
    private static final String COLUMNA_ID_PRODUCTO_ESPECIFICO = "idProductoEspecifico";
    private static final String COLUMNA_SUCURSAL = "idSucursal";
    private static final String COLUMNA_EXISTENCIA = "existencia";
    private static final String COLUMNA_PRECIO = "precio";
    private static final String COLUMNA_RUTA = "rutaImagen";
    private  HashMap<Class,Integer> tipos;
    private Connection conexion;
    private AccesoBaseDatos acceso = new AccesoBaseDatos();
    
    public DAOProducto(){
        this.conexion = this.acceso.abrirConexion();
        this.tipos = new HashMap<>();
        inicializaMapa();
    }
    
    public boolean insertarProducto(Producto producto, Sucursal sucursal){        
        if(producto instanceof TarjetaMadre){
            return insertaTarjetaMadre((TarjetaMadre)producto,sucursal);
        }else if(producto instanceof Procesador){
            return insertaProcesador((Procesador)producto,sucursal);
        }else if(producto instanceof DiscoDuro){
            return insertaDiscoDuro((DiscoDuro)producto,sucursal);
        }else if(producto instanceof Memoria){
            return insertaMemoria((Memoria)producto,sucursal);
        }else if(producto instanceof Gabinete){
            return insertaGabinete((Gabinete)producto,sucursal);
        }else if(producto instanceof Teclado){
            return insertaTeclado((Teclado)producto,sucursal);
        }else if(producto instanceof Raton){
            return insertaRaton((Raton)producto,sucursal);
        }else if(producto instanceof TarjetaVideo){
            return insertaTarjetaVideo((TarjetaVideo)producto,sucursal);
        }else if(producto instanceof Monitor){
            return insertaMonitor((Monitor)producto,sucursal);
        }else if(producto instanceof UnidadOptica){
            return insertarUnidadOptica((UnidadOptica)producto,sucursal);
        }else{
            return false;
        }
    }
    
    private void inicializaMapa(){
        tipos.put(TarjetaMadre.class, new Integer("0"));
        tipos.put(Procesador.class, new Integer("1"));
        tipos.put(DiscoDuro.class,new Integer("2"));
        tipos.put(Memoria.class,new Integer("3"));
        tipos.put(Gabinete.class,new Integer("4"));
        tipos.put(Teclado.class,new Integer("5"));
        tipos.put(Raton.class,new Integer("6"));
        tipos.put(TarjetaVideo.class, new Integer("7"));
        tipos.put(Monitor.class, new Integer("8"));
        tipos.put(UnidadOptica.class, new Integer("9"));
    }

    public HashMap<Class, Integer> getTipos() {
        return tipos;
    }
    
    private boolean existeProducto(Producto producto, int tipoProducto){
        boolean existe=false;
        String tabla="";
        switch(tipoProducto){
            case 0:
                tabla = "TarjetasMadre";
                break;
            case 1:
                tabla = "Procesadores";
                break;
            case 2:
                tabla = "DiscosDuro";
                break;
            case 3:
                tabla = "Memorias";
                break;
            case 4:
                tabla = "Gabinetes";
                break;
            case 5:
                tabla = "Teclados";
                break;
            case 6:
                tabla = "Ratones";
                break;
            case 7:
                tabla = "TarjetasVideo";
                break;
            case 8:
                tabla = "Monitores";
                break;
            case 9:
                tabla = "UnidadesOpticas";
        }
        
        try{
            
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String query = "SELECT * FROM "+tabla+" WHERE nombre='"+producto.getNombre()+"';";
            ResultSet resultado = sentencia.executeQuery(query);
            if(resultado.next()){
                System.out.println("Si existe");
                existe = true;
            }else{
                existe = false;
            }
        }
        catch (SQLException ex) {
            Logger.getLogger(DAOProducto.class.getName()).log(Level.SEVERE, null, ex);
        } 
        return existe;
    }
    
    private boolean insertaTarjetaMadre(TarjetaMadre tarjetaMadre,Sucursal sucursal) {
        if(!this.existeProducto(tarjetaMadre, (tipos.get(tarjetaMadre.getClass())).intValue())){
            DAOTarjetaMadre daotm = new DAOTarjetaMadre();
            TarjetaMadre tm = daotm.registrarTarjetaMadre(tarjetaMadre);
            if(tm!=null){
                if( this.registraProducto(tm, sucursal)){
                    //Se repetia la trataba de validar que exista esa tarjetaMadre
                    //la acaba de registrar y me retornaba 'false' siempre.
                    //return this.registraProductoSucursal(tm, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            DAOTarjetaMadre daoTarjetaMadre = new DAOTarjetaMadre();
            ArrayList<TarjetaMadre> listaDeTarjetasMadres = new ArrayList<>();
            listaDeTarjetasMadres = daoTarjetaMadre.listarTarjetasMadre();
            
            int existencia = tarjetaMadre.getExistencia();
            for(int i=0; i<listaDeTarjetasMadres.size(); i++){
                if(tarjetaMadre.getNombre().equals(listaDeTarjetasMadres.get(i).getNombre())){
                    tarjetaMadre = listaDeTarjetasMadres.get(i);
                    tarjetaMadre.setExistencia(existencia);
                    System.out.println("Se encontro la tarjeta");
                    break;
                }
            }
            return this.registraProductoSucursal(tarjetaMadre, sucursal);
        }
    }

    private boolean insertaProcesador(Procesador procesador,Sucursal sucursal) {
        if(!this.existeProducto(procesador, (tipos.get(procesador.getClass())).intValue())){
            DAOProcesador daoProcesador = new DAOProcesador();
            Procesador p = daoProcesador.insertaProcesador(procesador);
            if(p!=null){
                if( this.registraProducto(p, sucursal)){
                    //return this.registraProductoSucursal(p, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            return this.registraProductoSucursal(procesador, sucursal);
        }
    }

    private boolean insertaDiscoDuro(DiscoDuro discoDuro,Sucursal sucursal) {
        if(!this.existeProducto(discoDuro, (tipos.get(discoDuro.getClass())).intValue())){
            DAODiscoDuro daoDiscoDuro = new DAODiscoDuro();
            DiscoDuro dd = daoDiscoDuro.insertaDiscoDuro(discoDuro);
            if(dd!=null){
                if( this.registraProducto(dd, sucursal)){
                    //return this.registraProductoSucursal(dd, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            return this.registraProductoSucursal(discoDuro, sucursal);
        }
    }

    private boolean insertaMemoria(Memoria memoria,Sucursal sucursal) {
        if(!this.existeProducto(memoria, (tipos.get(memoria.getClass())).intValue())){
            DAOMemoria daomemoria = new DAOMemoria();
            Memoria m = daomemoria.insertaMemoria(memoria);
            if(m!=null){
                if( this.registraProducto(m, sucursal)){
                    //return this.registraProductoSucursal(m, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            return this.registraProductoSucursal(memoria, sucursal);
        }
    }

    private boolean insertaGabinete(Gabinete gabinete,Sucursal sucursal) {
        if(!this.existeProducto(gabinete, (tipos.get(gabinete.getClass())).intValue())){
            DAOGabinete daogabinete = new DAOGabinete();
            Gabinete g = daogabinete.insertarGabinete(gabinete);
            if(g!=null){
                if( this.registraProducto(g, sucursal)){
                    //return this.registraProductoSucursal(g, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            return this.registraProductoSucursal(gabinete, sucursal);
        }
    }

    private boolean insertaTeclado(Teclado teclado,Sucursal sucursal) {
        if(!this.existeProducto(teclado, (tipos.get(teclado.getClass())).intValue())){
            DAOTeclado daoteclado = new DAOTeclado();
            Teclado t = daoteclado.insertaTeclado(teclado);
            if(t!=null){
                if( this.registraProducto(t, sucursal)){
                    //return this.registraProductoSucursal(t, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            return this.registraProductoSucursal(teclado, sucursal);
        }
        
    }

    private boolean insertaRaton(Raton raton,Sucursal sucursal) {
        if(!this.existeProducto(raton, (tipos.get(raton.getClass())).intValue())){
            DAORaton daoraton = new DAORaton();
            Raton r = daoraton.insertaRaton(raton);
            if(r!=null){
                if( this.registraProducto(r, sucursal)){
                    //return this.registraProductoSucursal(r, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            return this.registraProductoSucursal(raton, sucursal);
        }
    }

    private boolean insertaTarjetaVideo(TarjetaVideo tarjetaVideo,Sucursal sucursal) {
        if(!this.existeProducto(tarjetaVideo, (tipos.get(tarjetaVideo.getClass())).intValue())){
            DAOTarjetaVideo daotv = new DAOTarjetaVideo();
            TarjetaVideo tv = daotv.insertarTarjetaVideo(tarjetaVideo);
            if(tv!=null){
                if( this.registraProducto(tv, sucursal)){
                    //return this.registraProductoSucursal(tv, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            return this.registraProductoSucursal(tarjetaVideo, sucursal);
        }
    }

    private boolean insertaMonitor(Monitor monitor,Sucursal sucursal) {
        if(!this.existeProducto(monitor, (tipos.get(monitor.getClass())).intValue())){
            DAOMonitor daomonitor = new DAOMonitor();
            Monitor m = daomonitor.insertarMonitor(monitor);
            if(m!=null){
                if( this.registraProducto(m, sucursal)){
                    //return this.registraProductoSucursal(m, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            return this.registraProductoSucursal(monitor, sucursal);
        }
    }
    
    private boolean registraProducto(Producto producto,Sucursal sucursal){
        try{
            Statement sentencia = conexion.createStatement();
            sentencia = this.acceso.crearSentenciaBD(conexion);
            String query = "INSERT INTO "+TABLA_PRODUCTOS+"("
                    +COLUMNA_ID_PRODUCTO_ESPECIFICO+","+COLUMNA_TIPO_PRODUCTO
                    +","+COLUMNA_PRECIO+","+COLUMNA_RUTA+") "
                    + "VALUES('"+producto.getClave()+"','"+(tipos.get(producto.getClass())).intValue()
                    +"','"+producto.getPrecio()+"','"+producto.getRutaImagen()+"');";
            int afectados = sentencia.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
            if(afectados == 0){
                return false;
            }else{
                ResultSet generado = sentencia.getGeneratedKeys();
                if(generado.next()){
                    int id = generado.getInt(1); 
                    return registraExistencia(id,producto.getExistencia(),sucursal);
                }else{
                    return false;
                }
            }
        }catch(SQLException sqlex){
            return false;
        }
    }
    //Para agregar un producto existente en la bd a una sucursal que no lo tiene registrado
    private boolean registraProductoSucursal(Producto producto, Sucursal sucursal){
        if(!existeProductoSucursal(producto, sucursal)){
            System.out.println("HEY");
            return false;
        }else{
            try{
                int claveProducto = buscaClaveProducto(producto);
                Statement sentencia = acceso.crearSentenciaBD(conexion);
                String query = "INSERT INTO "+TABLA_EXISTENCIAS+"("+COLUMNA_ID_PRODUCTO_EXISTENCIAS
                        +","+COLUMNA_SUCURSAL+","+COLUMNA_EXISTENCIA+") "
                        + "VALUES ('"+claveProducto+"','"+sucursal.getClaveSucursal()
                        +"','"+producto.getExistencia()+"');";
                System.out.println("query: "+query);
                if(sentencia.executeUpdate(query) == 0){
                    return true;
                }else{
                    return false;
                }
            }catch(SQLException sqlex){
                System.out.println("Error: " + sqlex);
                return false;
            }
        }
    }
    
    private boolean existeProductoSucursal(Producto producto, Sucursal sucursal){
        boolean existe=false;
        try{
            
            Statement sentencia = conexion.createStatement();
            sentencia = this.acceso.crearSentenciaBD(conexion);
            String query = "SELECT * FROM "+TABLA_PRODUCTOS+" WHERE "+COLUMNA_ID_PRODUCTO_ESPECIFICO
                    +"='"+producto.getClave()+"' AND "+COLUMNA_TIPO_PRODUCTO+"='"
                    +(tipos.get(producto.getClass())).intValue() +"'";
                    //+ " AND "+COLUMNA_SUCURSAL+"='"+sucursal.getClaveSucursal()+"'";
            ResultSet resultado = sentencia.executeQuery(query);
            if(resultado.next()){
                System.out.println("TRUE");
                existe = true;
            }else{
                System.out.println("FALSE");
                existe = false;
            }
        }
        catch (SQLException ex) {
            Logger.getLogger(DAOProducto.class.getName()).log(Level.SEVERE, null, ex);
        } 
        return existe;
    }

    private boolean registraExistencia(int id, int existencia, Sucursal sucursal) {
        try{
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String query = "INSERT INTO "+TABLA_EXISTENCIAS+"("+COLUMNA_ID_PRODUCTO_EXISTENCIAS+","
                    +COLUMNA_SUCURSAL+","+COLUMNA_EXISTENCIA+") VALUES('"+id+"','"
                    +sucursal.getClaveSucursal()+"','"+existencia+"');";
            int afectados = sentencia.executeUpdate(query);
            if(afectados == 0){
                return false;
            }else{
                return true;
            }
        }catch(SQLException sqlex){
            return false;
        }
    }
    
    
    public int obtenerExistenciaProducto(int idProducto){
        try{
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String query = "SELECT SUM("+COLUMNA_EXISTENCIA+") FROM "+TABLA_EXISTENCIAS
                    +" WHERE "+COLUMNA_ID_PRODUCTO_EXISTENCIAS+"='"+idProducto+"';";
            ResultSet resultado = sentencia.executeQuery(query);
            if(resultado.next()){
                int existenciaProducto = resultado.getInt(1);
                return existenciaProducto;
            }else{
                return -1;
            }
        }catch (SQLException sqlex){
            return -1;
        }
    }
    public int obtenerExistenciaProducto(int idProductoEspecifico,int tipoProducto){
        try{
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String query = "SELECT SUM("+COLUMNA_EXISTENCIA+") FROM "+TABLA_EXISTENCIAS
                    +" WHERE "+COLUMNA_ID_PRODUCTO_EXISTENCIAS+"='"+idProductoEspecifico
                    +"' AND "+COLUMNA_TIPO_PRODUCTO+"='"+tipoProducto+"' ;";
            ResultSet resultado = sentencia.executeQuery(query);
            if(resultado.next()){
                int existenciaProducto = resultado.getInt(1);
                return existenciaProducto;
            }else{
                return -1;
            }
        }catch (SQLException sqlex){
            return -1;
        }
    }
    
    public double obtenerPrecioProducto(int idProductoEspecifico,int tipoProducto){
        try{
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String query = "SELECT precio FROM Productos WHERE idProductoEspecifico='"
                    +idProductoEspecifico+"' AND tipoProducto='"+tipoProducto+"';";
            ResultSet resultado = sentencia.executeQuery(query);
            if(resultado.next()){
                return resultado.getDouble(1);
            }else{
                return 0.0;
            }
        }catch(SQLException ex){
            return 0.0;
        }
    }
    
    public String obtenerRutaImagen(int idProductoEspecifico,int tipoProducto){
        try{
            Statement sentencia = acceso.crearSentenciaBD(conexion);
            String query = "SELECT rutaImagen FROM Productos WHERE idProductoEspecifico='"
                    +idProductoEspecifico+"' AND tipoProducto='"+tipoProducto+"';";
            ResultSet resultado = sentencia.executeQuery(query);
            if(resultado.next()){
                return resultado.getString(1);
            }else{
                return "";
            }
        }catch(SQLException ex){
            return "";
        }
    }

    private int buscaClaveProducto(Producto producto) {
        try{
            Statement sentencia = conexion.createStatement();
            sentencia = this.acceso.crearSentenciaBD(conexion);
            String query = "SELECT idProducto FROM Productos WHERE idProductoEspecifico='"
                    +producto.getClave()+"' AND tipoProducto='"+(tipos.get(producto.getClass())).intValue()
                    +"';";
            ResultSet resultado = sentencia.executeQuery(query);
            if(resultado.next()){
                return resultado.getInt(1);
            }else{
                return -1;
            }
        }catch(SQLException ex){
            return -1;
        }
    }

    private boolean insertarUnidadOptica(UnidadOptica unidadOptica, Sucursal sucursal) {
        if(!this.existeProducto(unidadOptica, (tipos.get(unidadOptica.getClass())).intValue())){
            DAOUnidadOptica daounidad = new DAOUnidadOptica();
            UnidadOptica uo = daounidad.insertarUnidadOptica(unidadOptica);
            System.out.println("hey " + uo);
            if(uo!=null){
                if( this.registraProducto(uo, sucursal)){
                    //return this.registraProductoSucursal(uo, sucursal);
                    return true;
                }else{
                    return false;
                }
                
            }else{
                return false;
            }
        }else{
            return this.registraProductoSucursal(unidadOptica, sucursal);
        }
    }
}
